package edu.westga.src.javamin.main;
import com.cloudgarden.layout.AnchorConstraint;
import com.cloudgarden.layout.AnchorLayout;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.WindowConstants;
import javax.swing.border.LineBorder;
import javax.swing.SwingUtilities;
import org.jfugue.Pattern;
import org.jfugue.Player;

/**
 * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI
 * Builder, which is free for non-commercial use. If Jigloo is being used
 * commercially (ie, by a corporation, company or business for any purpose
 * whatever) then you should purchase a license for each developer using Jigloo.
 * Please visit www.cloudgarden.com for details. Use of Jigloo implies
 * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN
 * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR
 * ANY CORPORATE OR COMMERCIAL PURPOSE.
 */

public class MainDisplay extends javax.swing.JFrame implements
		MouseMotionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	{
		// Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private JPanel PlayArea;
	private JPanel jPanel1;
	private JButton playButton;
	private JTextField notesTextField;
	private JPanel jPanel2;
	private JTextArea output;
	private int theNote;
	private JButton uButton;
	private JButton downButton;
	private JLabel jLabel1;
	private JButton openSaveSong;
	private JButton saveFileButton;
	private JButton newSongButton;
	private JButton restButton;
	private int instrument;
	private int octave = 6;
	private Pattern thePattern = new Pattern();
	private Player jukebox = new Player();
	private ButtonGroup instGroup = new ButtonGroup();
	private File songfile = new File("song");
	private JTextArea helpTextArea;
	private JButton helpButton;
	private JLabel jLabel2;
	private JComboBox instrumentBox;
	private JFileChooser theFileChooser = new JFileChooser(songfile);
	private Component frame = null;


	/**
	 * Auto-generated main method to display this JFrame
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				MainDisplay inst = new MainDisplay();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}

	public MainDisplay() {
		super();
		initGUI();
	}

	/**
	 * makes the gui with a box to display mouse x and y values and a area to
	 * move the mouse in
	 */
	private void initGUI() {
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	setDefaultCloseOperation(MainDisplay.EXIT_ON_CLOSE);
			getContentPane().setLayout(null);
			this.setPreferredSize(new java.awt.Dimension(600, 308));
			this.setResizable(false);
			this.setTitle("Javamin Composer v 1.0");
			{
			jPanel2 = new JPanel();
				jPanel2.setLayout(null);
				getContentPane().add(
						jPanel2,
						new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0,
								GridBagConstraints.CENTER,
								GridBagConstraints.NONE,
								new Insets(0, 0, 0, 0), 0, 0));
				jPanel2.setBounds(412, 183, 85, 56);
				jPanel2.add(getJLabel1());
				jPanel2.add(getDownButton());
				jPanel2.add(getUButton());
			}
			{
				output = new JTextArea();
				getContentPane().add(output);
				output.setEditable(false);
				output.setBounds(503, 191, 81, 46);
				output.setBorder(new LineBorder(new java.awt.Color(0, 0, 0), 1,
						false));
			}
			{
				notesTextField = new JTextField();
				getContentPane().add(getNotesTextField());
				notesTextField.setBounds(12, 248, 380, 21);
				notesTextField.setEditable(false);
				notesTextField.setFont(new java.awt.Font("SansSerif",1,14));
			}
			{
				playButton = new JButton();
				getContentPane().add(playButton);
				getContentPane().add(getRestButton());
				getContentPane().add(getNewSongButton());
				getContentPane().add(getSaveFileButton());
				getContentPane().add(getOpenSaveSong());
				getContentPane().add(getJComboBox1());
				{
					jPanel1 = new JPanel();
					getContentPane().add(
							jPanel1,
							new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
									GridBagConstraints.CENTER,
									GridBagConstraints.NONE,
									new Insets(0, 0, 0, 0), 0, 0));
					getContentPane().add(getJButton1());
					jPanel1.setBounds(7, 10, 391, 238);
					ImageIcon icon = new
					ImageIcon("logo.jpeg");

					{
						PlayArea = new JPanel();
						jPanel1.add(PlayArea);
						PlayArea.setBackground(new java.awt.Color(255, 255, 255));
						PlayArea.addMouseMotionListener(this);
						PlayArea.setPreferredSize(new java.awt.Dimension(381, 228));
						PlayArea.setBorder(BorderFactory.createCompoundBorder(
								BorderFactory.createTitledBorder(""), null));
						PlayArea.setOpaque(false);
						PlayArea.setLayout(null);
						PlayArea.add(getJLabel2());

						PlayArea.addMouseListener(new MouseAdapter() {
							public void mouseClicked(MouseEvent evt) {
								PlayAreaMouseClicked(evt);
							}
						});
					}
				}
				playButton.setText("Play!");
				playButton.setBounds(410, 248, 174, 21);
				playButton.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						playButtonMouseClicked(evt);
					}
				});
			}

			restButton.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					restButtonMouseClicked(evt);
				}
			});
			pack();
			pack();
			pack();
			pack();
			pack();
			pack();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * gets the x and y values of the mouse and plays a sound while the mouse is
	 * in the given area
	 * 
	 * results: sound is played based on the position of the mouse
	 * 
	 * @param MouseEvent
	 *            e
	 */
	public void mouseMoved(MouseEvent e) {

		playOnMove(e);
	}

	private void playOnMove(MouseEvent e) {
		jukebox.close();
		theNote = ((e.getX()) / 30) + ((octave - 1) * 12);
		NoteMaker theMaker = new NoteMaker();
		String lNote = theMaker.makeNote(theNote);
		output.setText(e.getX() + ", " + e.getY() + "\n" + "note: " + lNote);
		jLabel1.setText("Octave: " + octave);
		if (e.getX() < 380 && e.getY() < 227) {

			jukebox.play("I" + instrument + " [" + theNote + "]");

		}
		jukebox.close();
	}

	private void SynthButtonMouseClicked(MouseEvent evt) {
		System.out.println("SynthButton.mouseClicked, event=" + evt);
		instrument = 92;
	}

	private void PianoButton1MouseClicked(MouseEvent evt) {
		System.out.println("PianoButton1.mouseClicked, event=" + evt);
		instrument = 0;
	}

	private void GuitarButtonMouseClicked(MouseEvent evt) {
		System.out.println("GuitarButton.mouseClicked, event=" + evt);
		instrument = 24;
	}

	public JTextField getNotesTextField() {
		return notesTextField;
	}

	private static String intToString(int aInt) {

		String aString = Integer.toString(aInt);
		return aString;

	}

	private void PlayAreaMouseClicked(MouseEvent evt) {
		String song = "";
		String pattern = "";
		song = notesTextField.getText();
		NoteMaker theMaker = new NoteMaker();
		notesTextField
				.setText(song + " "+ theMaker.makeNote((theNote)));
		pattern += "I" + instrument + " [" + theNote + "]id127";
		thePattern.add(pattern);
	}

	private void playButtonMouseClicked(MouseEvent evt) {

		jukebox.play(thePattern);
		jukebox.close();

	}

	private JButton getRestButton() {
		if (restButton == null) {
			restButton = new JButton();
			restButton.setText("Rest");
			restButton.setBounds(404, 122, 88, 23);
		}
		return restButton;
	}

	private void restButtonMouseClicked(MouseEvent evt) {
		String song = "";
		String pattern = "";
		song = notesTextField.getText();
		notesTextField.setText(song + " " + "Rw");
		pattern += "Ri";
		thePattern.add(pattern);
	}

	// Auto Gen Jigloo Code
	private JButton getNewSongButton() {
		if (newSongButton == null) {
			newSongButton = new JButton();
			newSongButton.setText("New Song");
			newSongButton.setBounds(498, 122, 86, 23);
			newSongButton.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					newSongButtonMouseClicked(evt);
				}
			});
		}
		return newSongButton;
	}

	private void newSongButtonMouseClicked(MouseEvent evt) {
		System.out.println("newSongButton.mouseClicked, event=" + evt);
		// TODO add your code for newSongButton.mouseClicked
		notesTextField.setText("");
		Pattern emptyPattern = new Pattern();
		thePattern = emptyPattern;
	}

	private JButton getSaveFileButton() {
		if (saveFileButton == null) {
			saveFileButton = new JButton();
			saveFileButton.setText("Save Song");
			saveFileButton.setBounds(404, 156, 180, 21);
			saveFileButton.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					saveFileButtonMouseClicked(evt);
				}
			});
		}
		return saveFileButton;
	}

	private void saveFileButtonMouseClicked(MouseEvent evt) {
		System.out.println("saveFileButton.mouseClicked, event=" + evt);
		// TODO add your code for saveFileButton.mouseClicked
		try {
		    theFileChooser.showSaveDialog(frame);
		    File selFile = theFileChooser.getSelectedFile();
			thePattern.savePattern(selFile);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// /DON"T TOUCH OR LOOK AT!!!!!!!!!!
	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	private JButton getOpenSaveSong() {
		if (openSaveSong == null) {
			openSaveSong = new JButton();
			openSaveSong.setText("Open Save Song");
			openSaveSong.setBounds(404, 91, 180, 20);
			openSaveSong.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					try {
						openSaveSongMouseClicked(evt);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		}
		return openSaveSong;
	}

	private void openSaveSongMouseClicked(MouseEvent evt) throws IOException {
		
		theFileChooser.showOpenDialog(frame);
		File selfile = theFileChooser.getSelectedFile();
		thePattern = Pattern.loadPattern(selfile);
		notesTextField.setText(thePattern.getMusicString());
	}

	private JLabel getJLabel1() {
		if (jLabel1 == null) {
			jLabel1 = new JLabel();
			jLabel1.setText("Octave:");
			jLabel1.setBounds(10, 0, 65, 14);
		}
		return jLabel1;
	}

	private JButton getDownButton() {
		if (downButton == null) {
			downButton = new JButton();
			downButton.setText("Down");
			downButton.setBounds(10, 35, 65, 21);
			downButton.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					downButtonMouseClicked(evt);
				}
			});
		}
		return downButton;
	}

	private void upButtonMouseClicked(MouseEvent evt) {
		System.out.println("upButton.mouseClicked, event="+evt);
		if (octave < 9)
		{
			octave = octave + 1;
			jLabel1.setText("Octave: " + octave);
		}
	}
	
	private void downButtonMouseClicked(MouseEvent evt) {
		System.out.println("downButton.mouseClicked, event="+evt);
		if (octave > 1)
		{
			octave = octave - 1;
			jLabel1.setText("Octave: " + octave);
		}
	}
	
			private JButton getUButton() {
				if (uButton == null) {
					uButton = new JButton();
					uButton.setText("Up");
					uButton.setBounds(10, 14, 65, 20);
					uButton.addMouseListener(new MouseAdapter() {
						public void mouseClicked(MouseEvent evt) {
							upButtonMouseClicked(evt);
						}
					});
				}
				return uButton;
			}
			
			private JComboBox getJComboBox1() {
				if(instrumentBox == null) {
					ComboBoxModel instrumentList = 
						new DefaultComboBoxModel(
								new String[] { "PIANO", 
										"BRIGHT ACOUSTIC",
										"ELECTRIC GRAND",
										"HONKEY TONK", 
										"ELECTRIC PIANO 1", 
										"ELECTRIC PIANO 2", 
										"HARPISCHORD", 
										"CLAVINET ",
										"CELESTA",
										"GLOCKENSPIEL",
										"MUSIC BOX",
										"VIBRAPHONE",
										"MARIMBA",
										"XYLOPHONE",
										"TUBULAR_BELLS",
										"DULCIMER",
										"DRAWBAR ORGAN",
										"PERCUSSIVE ORGAN",
										"ROCK ORGAN",
										"CHURCH ORGAN",
										"REED ORGAN",
										"ACCORIDAN",
										"HARMONICA",
										"TANGO ACCORDIAN",
										"GUITAR",
										"STEEL STRING GUITAR",
										"ELECTRIC JAZZ GUITAR",
										"ELECTRIC CLEAN GUITAR",
										"ELECTRIC MUTED GUITAR",
										"OVERDRIVEN GUITAR",
										"DISTORTION GUITAR",
										"GUITAR_HARMONICS",
										"ACOUSTIC BASS",
										"ELECTRIC BASS FINGER",
										"ELECTRIC BASS PICK",
										"FRETLESS BASS",
										"SLAP BASS 1",
										"SLAP BASS 2",
										"SYNTH BASS 1",
										"SYNTH BASS 2",
										"VIOLIN",
										"VIOLA",
										"CELLO",
										"CONTRABASS",
										"TREMOLO STRINGS",
										"PIZZICATO STRINGS",
										"ORCHESTRAL STRINGS",
										"TIMPANI",
										"STRING ENSEMBLE 1",
										"STRING ENSEMBLE 2",
										"SYNTH STRINGS 1",
										"SYNTH STRINGS 2",
										"CHOIR AAHS",
										"VOICE OOHS",
										"SYNTH VOICE",
										"ORCHESTRA HIT",
										"TRUMPET",
										"TROMBONE",
										"TUBA",
										"MUTED TRUMPET",
										"FRENCH HORN",
										"BRASS SECTION",
										"SYNTHBRASS 1",
										"SYNTHBRASS 2",
										"SOPRANO SAX",
										"ALTO SAX",
										"TENOR SAX",
										"BARITONE SAX",
										"OBOE",
										"ENGLISH HORN",
										"BASSOON",
										"CLARINET",
										"PICCOLO",
										"FLUTE",
										"RECORDER",
										"PAN FLUTE",
										"BLOWN BOTTLE",
										"SKAKUHACHI",
										"WHISTLE",
										"OCARINA",
										"LEAD SQUARE",
										"LEAD SAWTOOTH",
										"LEAD CALLIOPE",
										"LEAD CHIFF",
										"LEAD CHARANG",
										"LEAD FIFTHS",
										"LEAD BASSLEAD",
										"PAD NEW AGE",
										"PAD WARM",
										"PAD POLYSYNTH",
										"PAD CHOIR",
										"PAD BOWED",
										"PAD METALLIC",
										"PAD HALO",
										"PAD SWEEP",
										"FX RAIN",
										"FX SOUNDTRACK",
										"FX CRYSTAL",
										"FX ATMOSPHERE",
										"FX BRIGHTNESS",
										"FX GOBLINS",
										"FX ECHOES",
										"FX SCI-FI",
										"Ethnic",
										"SITAR",
										"BANJO",
										"SHAMISEN",
										"KOTO",
										"KALIMBA",
										"BAGPIPE",
										"FIDDLE",
										"SHANAI",
										"TINKLE BELL",
										"AGOGO",
										"STEEL DRUMS",
										"WOODBLOCK",
										"TAIKO DRUM",
										"MELODIC TOM",
										"SYNTH DRUM",
										"REVERSE CYMBAL",
										"GUITAR FRET NOISE",
										"BREATH NOISE",
										"SEASHORE",
										"BIRD TWEET",
										"TELEPHONE RING",
										"HELICOPTER",
										"APPLAUSE",
										"GUNSHOT"});
					instrumentBox = new JComboBox();
					instrumentBox.setModel(instrumentList);
					instrumentBox.setBounds(404, 24, 180, 22);
					instrumentBox.addItemListener(new ItemListener() {
						public void itemStateChanged(ItemEvent evt) {
							instrumentBoxItemStateChanged(evt);
						}
					});
				}
				return instrumentBox;
			}
			
			private void instrumentBoxItemStateChanged(ItemEvent evt) {
				System.out.println("instrumentBox.itemStateChanged, event="+evt);
				instrument = instrumentBox.getSelectedIndex();
			}
			
			private JLabel getJLabel2() {
				if(jLabel2 == null) {
					jLabel2 = new JLabel();
					jLabel2.setText("jLabel2");
					jLabel2.setBounds(0, 1, 380, 227);
					jLabel2.setIcon(new ImageIcon(getClass().getClassLoader().getResource("javaplay area.jpg")));
				}
				return jLabel2;
			}
			
			
			private JButton getJButton1() {
				if(helpButton == null) {
					helpButton = new JButton();
					helpButton.setText("Help");
					helpButton.setBounds(404, 57, 180, 23);
					helpButton.addMouseListener(new MouseAdapter() {
						public void mouseClicked(MouseEvent evt) {
							helpButtonMouseClicked(evt);
						}
					});
				}
				return helpButton;
			}
			
			private JDialog getHelpDialog() {
				JDialog helpDialog = null;
				if(helpDialog == null) {
				helpDialog = new JDialog(this);
					helpDialog.getContentPane().setLayout(null);
					helpDialog.setPreferredSize(new java.awt.Dimension(658, 628));
					helpDialog.setEnabled(true);
					helpDialog.setTitle("Help");
					helpDialog.setLocation(new java.awt.Point(300, 300));
					helpDialog.setMinimumSize(new java.awt.Dimension(658, 628));
					helpDialog.getContentPane().add(getHelpTextArea(), new AnchorConstraint(19, 985, 982, 16, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
				}
				return helpDialog;
			}
			private Component getJScrollPane2() {
				// TODO Auto-generated method stub
				return null;
			}

			private void helpButtonMouseClicked(MouseEvent evt) {
				System.out.println("helpButton.mouseClicked, event="+evt);
				//TODO add your code for helpButton.mouseClicked
				getHelpDialog().pack();
				getHelpDialog().setLocationRelativeTo(null);
				getHelpDialog().setVisible(true);
				
			}
			
			private JTextArea getHelpTextArea() {
				if(helpTextArea == null) {
					helpTextArea = new JTextArea();
					helpTextArea.setEditable(false);
					helpTextArea.setText("Welcome to the Javamin Composer!\n\nWhat do the numbers across the bottom mean?\nThe numbers that appear in this box represent which note\nyou have chosen and which instrument will play it.\n\nSelecting a note:\nMoving the cursor around in the play area will play a short sample\nof the note that is being hovered over.  When the desired note\nis found, simply click on it to add it to your song. \n\nSelecting an Instrument:\nThere are two ways to select an instrument to use:\n1.  You can choose from the three standard instruments at the top\n right hand corner of the window.\n2.  You can also choose from the full list by using the drop down\nbox directly underneath the presets.\n\nSelecting an Octave:\nTo select an octave, use the up/down arrows located just above\nthe play button.\n\nAdding a rest into the song:\nTo add a rest into your song, click the \"Rest button to the right\nof the screen.  This button will add a 1/8 rest.\n\nSaving and Loading Songs:\nTo save a song that you have created, click the \"Save Song\" button.\nA Dialog will open that allows you to name your song and choose\nwhere to save it.  In order to load a previously saved song,\nclick the Open Save song Button and choose the desired \tfile.");
					helpTextArea.setPreferredSize(new java.awt.Dimension(630, 572));
					helpTextArea.setBounds(10, 11, 630, 572);
				}
				return helpTextArea;
			}

	}

